﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace NMortgage.UI.Tests
{
    public static class NotificationAssert
    {
        public static void RaisePropertyChanged<TSubject, TProperty>(TSubject subject, Expression<Func<TSubject, TProperty>> propertyExpression, TProperty valueToSet, params Expression<Func<TSubject,object>>[] additionalPropertiesFired)
            where TSubject : INotifyPropertyChanged
        {
            var propertiesRaised = new List<string>();
            var handler = new PropertyChangedEventHandler((sender, args) =>
                                                              {
                                                                  propertiesRaised.Add(args.PropertyName);
                                                              });
            subject.PropertyChanged += handler;

            var name = propertyExpression.GetPropertyName();
            var setter = propertyExpression.GetPropertySetter();

            setter(subject, valueToSet);

            subject.PropertyChanged -= handler;

            var expectedProperties = additionalPropertiesFired.Select(x => x.GetPropertyName()).Concat(new[]{name}).ToList();

            foreach (var expected in expectedProperties)
            {
                if (!propertiesRaised.Contains(expected))
                    Assert.Fail("Subject did not raise property changed event on " + expected);
            }
        }
    }
}
